/* eslint-disable @typescript-eslint/no-require-imports */
const fs = require('fs')
const path = require('path')
const { yellow, log, cyan } = require('console-log-colors')
const isDev = process.env.NODE_ENV ? process.env.NODE_ENV.trim() === 'dev' : true
log(cyan.bold('开始处理异步化分包...'))
// 读取pages.json_co
const pagesConfig = (() => {
    const configPath = path.resolve(__dirname, 'src/pages.json') // @NOTE 这里要根据脚本执行的路径改一下
    const pages = fs.readFileSync(configPath, 'utf8')
    // @NOTE 移除注释
    let pagesJson = pages.replace(/\/\*.*\*\//g, '')
    pagesJson = pagesJson.replace(/\/\/.*/g, '')
    return JSON.parse(pagesJson)
})()

// 读取page.json中的异步分包（没有配置pages）
const asyncPackages = (pagesConfig.subPackages || []).filter((package) => package._asyncPackages)

// 写入app.json
const distPath = path.resolve(__dirname, `dist/${isDev ? 'dev' : 'build'}/mp-weixin`) // @NOTE 这里要根据脚本执行的路径改一下
const appJsonPath = path.resolve(distPath, 'app.json')
const appJson = JSON.parse(fs.readFileSync(appJsonPath, 'utf8'))

if (!appJson.subPackages) {
    appJson.subPackages = []
}
asyncPackages.forEach((package) => {
    const hasInject = appJson.subPackages.find((pack) => pack.root === package.root)
    if (hasInject) {
        return
    }
    appJson.subPackages.push({
        root: package.root,
        pages: [],
    })
})
fs.writeFileSync(appJsonPath, JSON.stringify(appJson))

// 寻找用到分包组件的地方，注入组件占位（不注入的话小程序会报错导致分包内组件无法使用）
const ignorePaths = []
let discrepancyVal = 0
ignorePaths.push(appJsonPath) // 过滤app.json
asyncPackages.forEach((package) => {
    ignorePaths.push(path.join(distPath, package.root)) // 过滤分包的内容
})
const injectPlaceholder = (filepath) => {
    // 判断是否用到了分包的组件
    const jsonConfig = require(filepath)
    if (!jsonConfig.usingComponents) {
        return
    }

    const subPackageComponents = []
    Object.keys(jsonConfig.usingComponents).forEach((componentName) => {
        const componentPath = jsonConfig.usingComponents[componentName]
        const targetSubPackage = asyncPackages.find((package) => componentPath.includes(`/${package.root}/`))
        if (targetSubPackage) {
            // 防止重复添加
            // eslint-disable-next-line @typescript-eslint/prefer-optional-chain
            if (jsonConfig.componentPlaceholder && jsonConfig.componentPlaceholder[componentName]) {
                return
            }
            discrepancyVal++ // diff 分包异步组件数量
            subPackageComponents.push(componentName)
        }
    })
    if (subPackageComponents.length === 0) {
        return
    }
    log.gray(`开始处理: ${filepath}`)
    if (!jsonConfig.componentPlaceholder) {
        jsonConfig.componentPlaceholder = {}
    }
    subPackageComponents.forEach((name) => {
        jsonConfig.componentPlaceholder[name] = 'view' // 占位符全用view组件
    })
    fs.writeFileSync(filepath, JSON.stringify(jsonConfig))
    log.gray(`处理完成: ${filepath}`)
    log.grey('组件名: ', subPackageComponents)
}
findJSON(distPath, ignorePaths, injectPlaceholder)
discrepancyVal > 0 ? log(cyan.bold('异步化分包处理完成')) : log(yellow.bold('没有需要处理的异步化分包'))
if (isDev) {
    log.white('Watching for changes...')
}

function findJSON(folder, ignorePaths, cb) {
    fs.readdirSync(folder).forEach((filename) => {
        const filepath = path.join(folder, filename)
        const isIgnore = ignorePaths.some((ignorePath) => filepath.startsWith(ignorePath))
        if (isIgnore) {
            return
        }
        const stat = fs.statSync(filepath)
        if (filename.endsWith('.json')) {
            cb(filepath)
            return
        }
        if (stat.isDirectory()) {
            findJSON(filepath, ignorePaths, cb) // 递归查询
        }
    })
}
